package com.fds.demo.wxay.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

public class WXPayRequest {

    public static final String USER_AGENT =
        "WXPaySDK/3.0.9" + " (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " "
            + System.getProperty("os.version") + ") Java/" + System.getProperty("java.version") + " HttpClient/"
            + HttpClient.class.getPackage().getImplementationVersion();

    /**
     * 请求，只请求一次，不做重试
     * 
     * @param urlSuffix
     * @param connectTimeoutMs
     * @param readTimeoutMs
     * @return
     * @throws Exception
     */
    private static String requestOnce(String urlSuffix, String domain, String appId, String data, int connectTimeoutMs, int readTimeoutMs)
        throws Exception {
        BasicHttpClientConnectionManager connManager;
        connManager = new BasicHttpClientConnectionManager(RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", SSLConnectionSocketFactory.getSocketFactory()).build(), null, null, null);

        HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connManager).build();

        String url = "https://" + domain + urlSuffix;
        HttpPost httpPost = new HttpPost(url);

        RequestConfig requestConfig =
            RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
        httpPost.setConfig(requestConfig);

        StringEntity postEntity = new StringEntity(data, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.addHeader("User-Agent", USER_AGENT + " " + appId);
        httpPost.setEntity(postEntity);
        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        return EntityUtils.toString(httpEntity, "UTF-8");
    }

    private static String request(String urlSuffix, String domain, String appId, String data, int connectTimeoutMs, int readTimeoutMs) throws Exception {
        return requestOnce(urlSuffix, domain, appId, data, connectTimeoutMs, readTimeoutMs);
    }

    /**
     * 可重试的，非双向认证的请求
     * @param urlSuffix
     * @param data
     * @param connectTimeoutMs
     * @param readTimeoutMs
     * @return
     */
    public static String requestWithoutCert(String urlSuffix, String domain, String appId, String data, int connectTimeoutMs, int readTimeoutMs) throws Exception {
        return request(urlSuffix, domain, appId, data, connectTimeoutMs, readTimeoutMs);
    }
}
